package com.ruibang.glass.portal.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Optional;

/**
 * 1 * @ClassName HttpUtils
 * 2 * @Author: HuangLB
 * 3 * @date 2020/12/23 15:57
 * 4 * @Version 1.0
 */
@Slf4j
public class HttpUtils {

    private static final String supportProtocols = "TLSv1.2";
    private static final String supportedCipherSuites = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,"
            + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,"
            + "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,"
            + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,"
            + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";

    public static String doPostJson(String url, String parameter) {
        String result = null;
        try {
            //创建Httpclient请求对象
            CloseableHttpClient client = null;
            //创建httpResponse响应对象
            CloseableHttpResponse response = null;
            try {
                //创建实例
                client = getCloseableHttpClient();
                // 创建Https Post请求
                HttpPost httpPost = buildHttpPost(url, parameter);
                // 执行http请求
                response = client.execute(httpPost);
                //获取数据
                result = responseProcess(response);
            } finally {
                //关闭请求连接
                if (client != null) {
                    client.close();
                }
                //关闭响应连接
                if (response != null) {
                    response.close();
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 创建实例
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    private static CloseableHttpClient getCloseableHttpClient() throws NoSuchAlgorithmException, KeyManagementException {
        // 采用绕过验证的方式处理https请求
        SSLContext sslcontext = createIgnoreVerifySSL();
        // 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext, supportProtocols.split(","),
                        supportedCipherSuites.split(","), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER))
                .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        HttpClients.custom().setConnectionManager(connManager);

        // 创建自定义的httpclient对象
        // CloseableHttpClient client = HttpClients.createDefault();
        return HttpClients.custom().setConnectionManager(connManager).build();

    }

    /**
     * 绕过验证
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sc = SSLContext.getInstance("SSLv3");
        // 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sc.init(null, new TrustManager[]{trustManager}, null);
        return sc;
    }

    private static HttpPost buildHttpPost(String url, String parameter) {
        // 创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);
        // 设置header信息
        // 指定报文头【Content-type】
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("appKey", "a594abf3-30f4-4757-bec4-3e5bddc8353a");
        // 设置参数
        StringEntity stringentity = new StringEntity(parameter, ContentType.create("application/json", "UTF-8"));
        //装填参数
        httpPost.setEntity(stringentity);
        return httpPost;
    }

    private static String responseProcess(CloseableHttpResponse response) throws IOException {
        // 获取结果实体
        HttpEntity entity = response.getEntity();
        String body = "";
        if (entity != null) {
            // 按指定编码转换结果实体为String类型
            body = EntityUtils.toString(entity, "UTF-8");
        }
        EntityUtils.consume(entity);
        // 释放链接
        response.close();
        return body;
    }
}
